<script lang="ts" setup>
import { ref, computed, type PropType } from 'vue';
import type { TableColumnData, TableData, PaginationProps, TableDraggable, TableChangeExtra } from '@arco-design/web-vue';
import { useI18n } from 'vue-i18n';

defineOptions({
  name: 'OpenSearchTable',
});

const props = defineProps({
  title: {
    type: String,
    default: undefined,
  },

  subTitle: {
    type: String,
    default: () => useI18n().t('settings.component.searchTable.subTitle'),
  },

  buttonText: {
    type: String,
    default: () => useI18n().t('settings.component.searchTable.buttonText'),
  },

  pagination: {
    type: Object as PropType<PaginationProps>,
    default: () => ({
      pageSize: 20,
    }),
  },

  pager: {
    type: Object as PropType<{ current?: number | undefined, total?: number | undefined }>,
    default: null,
  },

  columns: {
    type: Array as PropType<TableColumnData[]>,
    default: () => [],
  },

  data: {
    type: Array as PropType<TableData[]>,
    default: () => [],
  },

  rowKey: {
    type: String,
    default: 'id',
  },

  loading: {
    type: Boolean,
    default: false,
  },

  draggable: {
    type: Object as PropType<TableDraggable>,
    default: null,
  },

  tableClass: {
    type: [String, Array, Object],
    default: '',
  },
});

const emit = defineEmits(['search', 'dragend']);
const pageNumber = ref(1);

const paginationProps = computed(() => {
  return props.pager ? {
    ...props.pagination,
    ...props.pager,
  } : false;
});

const handleSubmit = () => {
  emit('search', 1, 'button');
}

const pageChange = (page: number) => {
  pageNumber.value = page;

  emit('search', pageNumber.value, 'page');
}

const refresh = (page?: number | string) => {
  if (typeof page !== 'undefined') {
    if (page === 'reset') {
      pageNumber.value = 1;
    }
    else {
      pageNumber.value = page as number;
    }
  }

  emit('search', pageNumber.value);
}

const onChange = (data: TableData[], extra: TableChangeExtra) => {
  if (extra.type === 'drag') {
    emit('dragend', data, extra);
  }
}

defineExpose({
  refresh,
});
</script>

<template>
  <OpenGeneralCard class="open-search-table" :title="props.title">
    <div class="search-table-before">
      <slot name="search-before"></slot>
    </div>

    <ACardMeta :title="$slots.header ? props.subTitle : ''" class="search-table-header">
      <template #description>
        <AForm layout="inline" :model="{}" @submit="handleSubmit">
          <slot name="header"></slot>

          <template v-if="$slots.header">
            <AFormItem hide-label>
              <ASpace>
                <AButton type="primary" html-type="submit" :disabled="props.loading">{{ props.buttonText }}</AButton>

                <slot name="additional-search-button"></slot>
              </ASpace>
            </AFormItem>

            <ADivider class="mt-12" />
          </template>

          <div class="w-full flex justify-between">
            <ASpace wrap>
              <slot name="header-button"></slot>
            </ASpace>

            <ASpace wrap>
              <slot name="header-button-extra"></slot>
            </ASpace>
          </div>
        </AForm>
      </template>
    </ACardMeta>

    <slot name="table-before"></slot>

    <template v-if="$slots.table">
      <slot name="table" :page-change="pageChange" :on-change="onChange" :loading="props.loading" :pagination="pagination" :bordered="false"></slot>
    </template>
    <template v-else>
      <ATable
        :class="props.tableClass"
        :row-key="props.rowKey"
        :loading="props.loading"
        :pagination="paginationProps"
        :columns="props.columns"
        :data="props.data"
        @page-change="pageChange"
        @change="onChange"
        :bordered="false"
        :draggable="props.draggable"
      >
        <template #columns>
          <slot name="columns"></slot>
        </template>
      </ATable>
    </template>
  </OpenGeneralCard>
</template>

<style lang="scss" scoped>
.open-search-table {
  .search-table-before {
    &:deep() {
      .arco-radio-group {
        .arco-radio {
          padding-left: 0;
        }
      }
    }
  }

  .search-table-header {
    margin-bottom: 15px;

    &:deep() {
      .arco-card-meta-title {
        margin-bottom: 15px;
        font-size: 14px;
      }

      .arco-form-item {
        .arco-form-item-wrapper-col {
          min-width: 210px;
        }
      }
    }
  }

  :deep(.arco-table) {
    .arco-table-td-content {
      .arco-image {
        .arco-image-img {
          max-width: inherit;
          max-height: inherit;
        }
      }

      .button-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        align-items: center;
      }
    }
  }
}
</style>
